﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CoreRay
{
    internal class GridVoxel
    {
        public GridVoxel()
        {
            this.GeometryObjectCacheEntries = new List<GeometryObjectRayCache>(1);
        }

        public List<GeometryObjectRayCache> GeometryObjectCacheEntries
        {
            get;
            private set;
        }

        public Intersection Intersect(Ray ray, int rayId)
        {
            Intersection intersection = null;

            for (int i = 0; i < this.GeometryObjectCacheEntries.Count; i++)
            {
                var geometryObjectCacheEntry = this.GeometryObjectCacheEntries[i];

                //Check to see if the geometry object was already checked by the current ray
                if (geometryObjectCacheEntry.LastRayId == rayId)
                {
                    continue;
                }

                //Assign the ray id to the last checked ray id property of the geometry object cache
                geometryObjectCacheEntry.LastRayId = rayId;

                //Check if the geometry object's bounding box intersects the ray
                if (geometryObjectCacheEntry.GeometryObject.BoundingBox.Intersect(ray))
                {
                    //Check if the geometry object intersects the ray
                    Intersection result = geometryObjectCacheEntry.GeometryObject.Intersect(ray);

                    //Check to see if the intersection rayT is smaller than the current intersection rayT
                    if (result != null && (intersection == null || intersection.RayT > result.RayT))
                    {
                        intersection = result;
                    }
                }
            }

            return intersection;
        }

        public bool IntersectPosition(Ray ray, int rayId)
        {
            for (int i = 0; i < this.GeometryObjectCacheEntries.Count; i++)
            {
                var geometryObjectCacheEntry = this.GeometryObjectCacheEntries[i];

                //Check to see if the geometry object was already checked by the current ray
                if (geometryObjectCacheEntry.LastRayId == rayId)
                {
                    continue;
                }

                //Assign the ray id to the last checked ray id property of the geometry object cache
                geometryObjectCacheEntry.LastRayId = rayId;

                //Check if the geometry object intersects the ray
                if (geometryObjectCacheEntry.GeometryObject.BoundingBox.Intersect(ray) && geometryObjectCacheEntry.GeometryObject.IntersectPosition(ray))
                {
                    return true;
                }
            }

            return false;
        }
    }
}
